package com.lulalei.dbviewer.controller;

import com.lulalei.dbviewer.commons.api.ResultBean;
import com.lulalei.dbviewer.commons.bean.DBParameter;
import com.lulalei.dbviewer.commons.bean.JDBCConnectBean;
import com.lulalei.dbviewer.commons.bean.TableBean;
import com.lulalei.dbviewer.commons.cache.CacheManager;
import com.lulalei.dbviewer.commons.cache.CacheMap;
import com.lulalei.dbviewer.commons.enums.DatabaseTypeEnums;
import com.lulalei.dbviewer.commons.exception.CustomizeException;
import com.lulalei.dbviewer.commons.utils.PomReaderUtils;
import com.lulalei.dbviewer.dto.DBConnectDTO;
import com.lulalei.dbviewer.dto.DBTablesInfoDTO;
import com.lulalei.dbviewer.dto.GenerateDTO;
import com.lulalei.dbviewer.service.ViewerService;
import com.lulalei.dbviewer.vo.LinkedDBVO;
import com.lulalei.dbviewer.vo.PageVO;
import lombok.RequiredArgsConstructor;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/viewer")
public class ViewerController {

    private final ViewerService viewerService;

    private final DBParameter dbParameter;

    @GetMapping("/linkedDBs")
    public ResultBean<List<LinkedDBVO>> getLinkDBs() {
        return viewerService.getLinkDBs();
    }

    /**
     * 连接数据库
     *
     * @param dbConnectDTO 数据库连接参数
     * @return 通用返回结果
     */
    @PostMapping("/connect")
    public ResultBean<Boolean> connect(@RequestBody @Validated DBConnectDTO dbConnectDTO) throws CustomizeException, SQLException {
        DatabaseTypeEnums dbType = dbConnectDTO.getDbType();
        if (dbType == null) {
            throw new CustomizeException("不匹配的数据库类型");
        }
        dbConnectDTO.setDriverClassName(dbType.getDriver());
        if (dbConnectDTO.getFlag() == 1) {
            //从yml中获取参数
            getDBParameterForYml(dbConnectDTO);
        } else {
            //校验从前端获取的参数是否存在
            verifyDBParameter(dbConnectDTO);
        }
        return viewerService.connect(dbConnectDTO);
    }

    /**
     * 获取所有的表信息
     */
    @PostMapping("/tablesInfo")
    public ResultBean<PageVO<TableBean>> tablesInfo(@RequestBody @Validated DBTablesInfoDTO dbTablesInfoDTO) throws CustomizeException, SQLException {
        return viewerService.getTablesInfo(dbTablesInfoDTO);
    }

    /**
     * 获取该项目的子模块
     */
    @GetMapping("/modules")
    public ResultBean<List<String>> getModules() {
        try {
            List<String> rootMoulds = PomReaderUtils.getModules(PomReaderUtils.getRootPomModel());
            return ResultBean.success(rootMoulds);
        } catch (XmlPullParserException | IOException e) {
            e.printStackTrace();
        }
        return ResultBean.failure("操作失败");
    }


    /**
     * 生成代码
     */
    @PostMapping("/generate")
    public ResultBean<String> generate(@RequestBody @Validated GenerateDTO generateDTO) throws CustomizeException {
        try {
            CacheMap jdbc = CacheManager.getCacheMap("jdbc");
            JDBCConnectBean connectBean = (JDBCConnectBean) jdbc.get(generateDTO.getConnectionName());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultBean.failure("不存在的连接,请连接数据库后再继续生成");
        }

        return viewerService.generate(generateDTO);
    }

    //从yaml中获取数据库连接参数,并添加到入参的类中
    private void getDBParameterForYml(DBConnectDTO dbConnectDTO) throws CustomizeException {

        //检查参数是否获取到
        if (dbParameter == null) {
            throw new CustomizeException("参数获取失败,请检查");
        } else {
            if (dbParameter.getUsername() == null) {
                throw new CustomizeException("参数获取失败,请检查");
            }
            if (dbParameter.getPassword() == null) {
                throw new CustomizeException("参数获取失败,请检查");
            }
            if (dbParameter.getUrl() == null) {
                throw new CustomizeException("参数获取失败,请检查");
            }
            if (dbParameter.getDriverClassName() == null) {
                throw new CustomizeException("参数获取失败,请检查");
            }
        }
        dbConnectDTO.setPassword(dbParameter.getPassword());
        dbConnectDTO.setUsername(dbParameter.getUsername());
        dbConnectDTO.setUrl(dbParameter.getUrl());
        dbConnectDTO.setDriverClassName(dbParameter.getDriverClassName());

        //获取数据库名称
        String url = dbParameter.getUrl();
        int i = url.indexOf("?");
        if (i > -1) {
            dbConnectDTO.setDbName(url.substring(url.lastIndexOf("/") + 1, i));
        } else {
            dbConnectDTO.setDbName(url.substring(url.lastIndexOf("/") + 1));
        }
    }


    private void verifyDBParameter(DBConnectDTO dbConnectDTO) throws CustomizeException {
        if (dbConnectDTO.getUsername() == null) {
            throw new CustomizeException("请上传完整的数据库参数");
        }
        if (dbConnectDTO.getPassword() == null) {
            throw new CustomizeException("请上传完整的数据库参数");
        }
        if (dbConnectDTO.getUrl() == null) {
            throw new CustomizeException("请上传完整的数据库参数");
        }
        if (dbConnectDTO.getDriverClassName() == null) {
            throw new CustomizeException("请上传完整的数据库参数");
        }
    }


}
